/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/*---------------------------------------------------------------------*/

#include "usb.h"
#include "usb_req_class.h"
#include "string.h"
#include "uart.h"
#include <stdio.h>

BYTE bHidIdle;
uint16_t bKeyCode = 0;
BYTE bKeyDebounce = 0;
BOOL fKeyOK;

sbit LED_NUM        = P4^3;
sbit LED_CAPS       = P4^2;
sbit LED_SCROLL     = P4^1;

void usb_req_class()
{
    switch (Setup.bRequest)
    {
    case GET_REPORT:
        usb_get_report();
        break;
    case SET_REPORT:
        usb_set_report();
        break;
    case GET_IDLE:
        usb_get_idle();
        break;
    case SET_IDLE:
        usb_set_idle();
        break;
    case GET_PROTOCOL:
        usb_get_protocol();
        break;
    case SET_PROTOCOL:
        usb_set_protocol();
        break;
    default:
        usb_setup_stall();
        return;
    }
}

void usb_get_report()
{
    if ((DeviceState != DEVSTATE_CONFIGURED) ||
        (Setup.bmRequestType != (IN_DIRECT | CLASS_REQUEST | INTERFACE_RECIPIENT)))
    {
        usb_setup_stall();
        return;
    }

    Ep0State.pData = UsbBuffer;
    Ep0State.wSize = Setup.wLength;

    usb_setup_in();
}

void usb_set_report()
{
    if ((DeviceState != DEVSTATE_CONFIGURED) ||
        (Setup.bmRequestType != (OUT_DIRECT | CLASS_REQUEST | INTERFACE_RECIPIENT)))
    {
        usb_setup_stall();
        return;
    }

    Ep0State.pData = UsbBuffer;
    Ep0State.wSize = Setup.wLength;

    usb_setup_out();
}

void usb_get_idle()
{
    if ((DeviceState != DEVSTATE_CONFIGURED) ||
        (Setup.bmRequestType != (IN_DIRECT | CLASS_REQUEST | INTERFACE_RECIPIENT)))
    {
        usb_setup_stall();
        return;
    }

    Ep0State.pData = &bHidIdle;
    Ep0State.wSize = 1;

    usb_setup_in();
}

void usb_set_idle()
{
    if ((DeviceState != DEVSTATE_CONFIGURED) ||
        (Setup.bmRequestType != (OUT_DIRECT | CLASS_REQUEST | INTERFACE_RECIPIENT)))
    {
        usb_setup_stall();
        return;
    }

    bHidIdle = Setup.wValueH;

    usb_setup_status();
}

void usb_get_protocol()
{
    usb_setup_stall();
}

void usb_set_protocol()
{
    usb_setup_stall();
}

void usb_class_out()
{
    BYTE led;
    
    if (usb_bulk_intr_out(UsbBuffer, 1) == 1)
    {
        P4M0 &= ~0x0f;
        P4M1 &= ~0x0f;
        P40 = 0;
        
        led = UsbBuffer[0];
        LED_NUM = !(led & 0x01);
        LED_CAPS = !(led & 0x02);
        LED_SCROLL = !(led & 0x04);
    }
}

void usb_class_in()
{
    BYTE key[9];
    BYTE i;
    BYTE keyindex;
		char buffer[100];
    
    if (DeviceState != DEVSTATE_CONFIGURED)
        return;
//		sprintf(buffer,"UsbInBusy = %x, fKeyOK = %x \r\n",UsbInBusy,fKeyOK);
//    PrintString1(buffer);
    if (!UsbInBusy && fKeyOK)
    {
        fKeyOK = 0;

        memset(key, 0, 9);

        key[0] = ((bKeyCode & 0x04) >> 2) | (bKeyCode & 0x2) << 1;
        keyindex = 2;
        if(bKeyCode & 0x1) key[keyindex++] = 0x2b; //Tab
        if(bKeyCode & 0x8) key[keyindex++] = 0x06; //c
        if(bKeyCode & 0x10) key[keyindex++] = 0x1d;//z
        if(bKeyCode & 0x20) key[keyindex++] = 0x19;//v
        if(bKeyCode & 0x40) key[keyindex++] = 0x1b;//x
        if(bKeyCode & 0x80) key[keyindex++] = 0x4c;//Del
				if(bKeyCode & 0x100) key[keyindex++] = 0x29;//Esc
				
				EUSB = 0;
				UsbInBusy = 1;
				usb_write_reg(INDEX, 1);
				for (i=0; i<8; i++)
				{
						usb_write_reg(FIFO1, key[i]);
						sprintf(buffer,"key[%x] = %x \r\n",i,key[i]);
						PrintString1(buffer);
				}
				
				usb_write_reg(INCSR1, INIPRDY);
				EUSB = 1;
				
    }
}

void scan_key()
{
    BYTE key1,key2;
    uint16_t key;
    char buffer[100];

    
    key1 = 0;
    key2 = 0;
    _nop_();
    _nop_();
    key1 |= P2;
    key2 |= P5;
    key = ~((key2 << 8) | key1);
    /*按键和引脚映射
    ["Esc" P5.0],
    ["Tab" P2.0,"Del" P2.7],
    ["Alt" P2.1,"Z" P2.4,"X" P2.6],
    ["Ctrl" P2.2,"C" P2.3,"V" P2.5]
    
    */
		sprintf(buffer,"key = %x, bKeyCode = %x,bKeyDebounce = %x \r\n",key,bKeyCode,bKeyDebounce);
//    PrintString1(buffer);
    if (key != bKeyCode)
    {
        bKeyCode = key;
        bKeyDebounce = 5;
    }
    else
    {
        if (bKeyDebounce)
        {
            bKeyDebounce--;
            if (bKeyDebounce == 0)
            {
                fKeyOK = 1;
            }
        }
    }
    
}

